namespace CRM_Perf_BenchMark
{
    using System;
    using System.Collections.Generic;
    using Microsoft.VisualStudio.TestTools.WebTesting;
    using System.Net;
    using System.Text;
    using System.Xml;    

    /// <summary>
    /// 1. Start at Settings homepage
    /// 2. Select Customization from the left menu
    /// 2. Select Customize Entities
    /// 3. Select New button
    /// 4. Enter in Name (with datetimestamp)
    /// 5. Enter Plural Name (with datetimestamp)
    /// 6. Enter Schema Name (with datetimestamp)
    /// 7. Select OK
    /// </summary>

    public class CreateEntity : CrmWebTest
    {
        public void CreateEntity_PreWebTest(object sender, PreWebTestEventArgs e)
        {
            EntityRequest er = new EntityRequest();
            er.Type = EntityNames.Users;
            er.ReturnAs = EntityNames.Users;
            er.ParentID = EntityManager.Instance.OrgId;

            System.Collections.Hashtable userProps = new System.Collections.Hashtable();
            if (e.WebTest.Context.ContainsKey("UserRole"))
            {
                userProps.Add("role", e.WebTest.Context["UserRole"]);
                er.Props = userProps;
            }
            
            System.Collections.Hashtable Entities = EntityManager.Instance.GetEntities(er);

            user = (CRMEntity)Entities[EntityNames.Users];

            crmServer = user["CrmServer"];
            tokenKey = EntityManager.Instance.ReadTokenKey(user["organizationid"]);

            e.WebTest.UserName = user["domainName"];
            e.WebTest.Password = user["userpassword"];            
        }

        public void CreateEntity_PostWebTest(object sender, PostWebTestEventArgs e)
        {
            EntityManager.Instance.FreeEntity(user);
        }

        public CreateEntity()
        {
            WebRequest.RegisterPrefix("crm", new crmRequestFactory());
            xmlData = Helper.GenerateEntityXml();
            gridXml = GridXmlHelper.EntityPageView(-1, customizableEntitiesView, null);

            this.Proxy = null;            
            PreWebTest += new EventHandler<PreWebTestEventArgs>(CreateEntity_PreWebTest);
            PostWebTest += new EventHandler<PostWebTestEventArgs>(CreateEntity_PostWebTest);
        }

        public override IEnumerator<WebTestRequest> GetRequestEnumerator()
        {
            this.BeginTransaction("NavCustomizationHomepage");

            tools_systemcustomization_systemcustomization_aspx customization = new tools_systemcustomization_systemcustomization_aspx(user);
            yield return (customization);

            this.EndTransaction("NavCustomizationHomepage");

            this.BeginTransaction("NavCustomizeEntities");

            customization = new tools_systemcustomization_systemcustomization_aspx(user);
            customization.pid = 01;
            yield return (customization);

            tools_systemcustomization_entities_entitylist_aspx entList = new tools_systemcustomization_entities_entitylist_aspx(user);
            yield return (entList);

            this.EndTransaction("NavCustomizeEntities");

            this.BeginTransaction("CreateEntity");

            tools_systemcustomization_entities_manageentity_aspx manEnt = new tools_systemcustomization_entities_manageentity_aspx(user);
            yield return (manEnt);

            referer = manEnt.lastResponse.ResponseUri.AbsoluteUri;

            SystemCustomization.SystemCustomization scws = new SystemCustomization.SystemCustomization();
            CrmRequest createEntity = null;
            try { scws.CreateEntity(xmlData); }
            catch (crmException x)
            {
                createEntity = (CrmRequest)x.wtr;
                createEntity.Url = Utils.ReplaceServerName(createEntity.Url, user);

                string urlPath = createEntity.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                createEntity.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                createEntity.Headers.Add(headerItem);
                createEntity.Method = "Post";
            }
            yield return (createEntity);

            //get the newly created Entity id out of the post reply
            int idIdx = createEntity.lastResponse.BodyString.IndexOf(newIdMarker);
            //Force casting it through a GUID ensures that the test actually worked. We'll get a format exception if the create didn't work.
            string tempNewEntityId = createEntity.lastResponse.BodyString.Substring(idIdx + (CreateEntity.newIdMarker.Length), 36);
            newEntityId = new Guid(tempNewEntityId);

            tools_systemcustomization_entities_manageentity_aspx me = new tools_systemcustomization_entities_manageentity_aspx(user);
            me.entityId = newEntityId;
            //me.Method = "Post";
            //headerItem = new WebTestRequestHeader();
            //headerItem.Name = "referer";
            //headerItem.Value = referer;
            //me.Headers.Add(headerItem);
            yield return (me);

            AppGridWebService.AppGridWebService agws = new AppGridWebService.AppGridWebService();
            CrmRequest wtrRefresh = null;
            try { agws.Refresh(gridXml); }
            catch (crmException x)
            {
                wtrRefresh = (CrmRequest)x.wtr;
                wtrRefresh.Url = Utils.ReplaceServerName(wtrRefresh.Url, user);

                string urlPath = wtrRefresh.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtrRefresh.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtrRefresh.Headers.Add(headerItem);
                wtrRefresh.Method = "Post";
            }
            yield return (wtrRefresh);

            _Common_icon_aspx icon = new _Common_icon_aspx(user);
            icon.objectTypeCode = 10000;
            icon.iconType = "gridIcon";
            icon.inProduction = 0;
            icon.cache = 1;
            yield return (icon);

            icon = new _Common_icon_aspx(user);
            icon.objectTypeCode = 10000;
            icon.iconType = "LargeEntityIcon";
            icon.inProduction = 0;
            icon.cache = 1;
            yield return (icon);

            this.EndTransaction("CreateEntity");

            XmlNode publishData = Helper.GeneratePublishXml(newEntityId);

            this.BeginTransaction("PublishEntity");

            scws = new SystemCustomization.SystemCustomization();
            CrmRequest publishEntity = null;
            try { scws.PublishCustomizations(publishData); }
            catch (crmException x)
            {
                publishEntity = (CrmRequest)x.wtr;
                publishEntity.Url = Utils.ReplaceServerName(publishEntity.Url, user);

                string urlPath = publishEntity.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                publishEntity.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                publishEntity.Headers.Add(headerItem);
                publishEntity.Method = "Post";
            }
            yield return (publishEntity);

            this.EndTransaction("PublishEntity");
        }

        private const string newIdMarker = @"<CreateEntityResult>";
        private CRMEntity user;
        private XmlNode xmlData;
        private string gridXml;
        private Guid newEntityId;
        private string crmServer;
        private string tokenKey;
        private static string customizableEntitiesView = "35AC1075-2E24-4215-8AAF-29DA7053BF8B";

        private WebTestRequestHeader headerItem;
        private WRPCInfo rpcInfo;
        private string referer;
    }
}